home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 008 / bonus.arc / TOWER.LSP < prev   
Encoding:
Lisp/Scheme  |  1985-03-12  |  5.3 KB  |  149 lines

  1. ;
  2. ;       Tower of Hanoi
  3. ;
  4. ;                               Kelvin R. Throop   March 1985
  5. ;
  6. ;       This file implements the Tower of Hanoi problem.  It is as
  7. ;       specified in the rules:
  8. ;
  9. ;          1.  Only one disc may be moved at a time.
  10. ;          2.  No disc may be placed on top of a smaller one.
  11. ;
  12. ;       The only incompatibility with the original is that the universe
  13. ;       will not come to an end when this function completes (however, if
  14. ;       you run it with the specified number of discs, 64, the protons may
  15. ;       decay before it's done).
  16. ;
  17. ;       One defines the tower with the command TOWER, which asks for the
  18. ;       number of discs.  Scaling is automatic, as is clearing away of any
  19. ;       previous execution.  Once the tower is defined, the solution may
  20. ;       be accomplished with the command SOLVE.
  21. ;
  22. ;       The solution function, TRANSFER, is as given in Winston and Horn,
  23. ;       "LISP", second edition, pp. 112-114.
  24. ;
  25. (defun C:TOWER ()
  26.  
  27.         (setq nrings (getint "Enter number of rings: "))
  28.  
  29.         (setq bthick 1)            ; base thickness
  30.         (setq rthick 1)            ; ring thickness
  31.         (setq smring 1.5)          ; smallest ring
  32.         (setq ringinc 1.0)         ; ring size increment
  33.         (setq postdia 1)           ; post diameter
  34.         (setq airspace 0.1)        ; air space between rings
  35.  
  36.         (setq lring (+ smring (* nrings ringinc))) ; largest ring diameter
  37.         (setq posta nil postb nil postc nil)       ; clear possible earlier run
  38.         (setq postl '(posta postb postc))          ; list of post lists
  39.         (setq rspace (+ rthick airspace))          ; ring vertical spacing
  40.  
  41.         (setvar "blipmode" 0)      ; get rid of annoying distractions
  42.         (setvar "cmdecho" 0)       ; disable echoing of commands
  43.         (setvar "fillmode" 0)      ; make for better display
  44.  
  45.         ; Clean up if previous display on screen
  46.  
  47.         (if before (progn
  48.               (command "vpoint" "0,0,0")
  49.               (setq a 1)
  50.               (while (<= a before)
  51.                  (command "erase" "l" "")
  52.                  (setq a (1+ a))
  53.               )
  54.               (command "layer" "set" "base" "")
  55.            )
  56.            (progn
  57.               (command "layer" "new" "base,1,2,3,4,5,6"
  58.                  "colour" 7 "base"
  59.               )
  60.               (setq a 0)
  61.               (while (<= (setq a (1+ a)) 6)
  62.                  (command "colour" a a)
  63.               )
  64.               (command "set" "base" "")
  65.            )
  66.         )
  67.  
  68.         ; Draw the base
  69.  
  70.         (command "elev" 0 bthick)
  71.         (setq a (+ lring (* postdia 2)))
  72.         (setq b (+ (* 3 (+ postdia lring)) postdia))
  73.         (command "vpoint" "0,0,0") ; insure ZOOM does the right thing
  74.         (command "solid" '(0 0) (list 0 a) (list b 0) (list b a))
  75.         (command)                  ; terminate solid
  76.         (command "zoom" "e")
  77.  
  78.         ; Draw the posts
  79.  
  80.         (command "elev" bthick (* rspace (1+ nrings)))
  81.         (setq a (+ postdia lring))
  82.         (setq b (+ postdia (/ lring 2)))
  83.         (setq postposy (+ postdia (/ lring 2)))
  84.         (setq postposx (list b (+ b a) (+ b a a)))
  85.         (command "circle" (list (car postposx) postposy) "d" postdia)
  86.         (command "circle" (list (cadr postposx) postposy) "d" postdia)
  87.         (command "circle" (list (caddr postposx) postposy) "d" postdia)
  88.         (setq bthick (+ bthick airspace))    ; offset position of lowest ring
  89.         (command "vpoint" "1,1,1") ; establish viewpoint
  90.  
  91.         ; Put rings on post 1 initially
  92.  
  93.         (setq i 1 l 5)
  94.         (setq d bthick)
  95.         (setq r (/ lring 2))
  96.         (while (<= i nrings)
  97.            (command "layer" "set" (1+ (setq l (rem (1+ l) 6))) "")
  98.            (command "elev" d rthick)
  99.            (command "circle" (list b postposy) r)
  100.            (setq posta (cons (list r (1+ l)) posta))
  101.            (setq r (- r (/ ringinc 2)))
  102.            (setq d (+ d rspace))
  103.            (setq i (1+ i))
  104.         )
  105.  
  106.         ; Tell the user how to proceed
  107.  
  108.         (setq before (+ nrings 4)) ; save previous ring count
  109.         (princ "\nType SOLVE to perform the solution.\n")
  110. )
  111.  
  112. ; Command function to perform solution
  113.  
  114. (defun C:SOLVE ()
  115.         (transfer 1 2 3 nrings)
  116.         (redraw)
  117. )
  118.  
  119. ; Move disc from one post to another
  120.  
  121. (defun move-disc (from to)
  122.         (setq lfrom (nth (1- from) postl))
  123.         (setq lto (nth (1- to) postl))
  124.         (setq elfrom (eval lfrom))
  125.         (setq elto (eval lto))
  126. ; **    (print (list 'Move 'disc 'from lfrom 'to lto))
  127.         (setq top (car elfrom))
  128.         (set lfrom (cdr elfrom))
  129.         (command "layer" "set" (cadr top) "")
  130.         (command "elev" (+ bthick (* (length elfrom) rspace)) rthick)
  131.         (command "erase" (list (nth (1- from) postposx)
  132.                                (+ postposy (car top))) "")
  133.         (command "elev" (+ bthick (* (length elto) rspace)) rthick)
  134.         (command "circle" (list (nth (1- to) postposx) postposy) (car top))
  135.         (set lto (cons top elto))
  136. )
  137.  
  138. ; Perform transfer of discs  (This is actually the entire solver)
  139.  
  140. (defun transfer (from to spare n)
  141.         (cond ((= n 1) (move-disc from to))
  142.               (t (transfer from spare to (1- n))
  143.                  (move-disc from to)
  144.                  (transfer spare to from (1- n)
  145.               )
  146.            )
  147.         )
  148. )
  149.